package com.wn.common.net

import com.wn.common.BuildConfig
import com.wn.common.net.config.*
import com.wn.common.net.support.LiveDataCallAdapterFactory
import com.wn.common.utils.HostInterceptor
import com.wn.common.utils.getBaseHost
import okhttp3.Cache
import okhttp3.OkHttpClient
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.io.File
import java.util.concurrent.TimeUnit

/**
 * @Author: wn
 * @Date: 2022/12/21 16:40
 * @Description: 封装的retrofit请求类 -- API  返回 -- LiveData<ApiResponse>
 * hilt 提供 network
 */

object KtRetrofit {
  //  创建 OkHttpClient
  private val mOkClient by lazy {
    OkHttpClient.Builder()
      .callTimeout(10, TimeUnit.SECONDS) // 完整请求超时时长，从发起到接收返回数据，默认值0s，不限定
      .connectTimeout(10, TimeUnit.SECONDS) // 与服务器建立连接的时长，默认--10s  秒
      .readTimeout(10, TimeUnit.SECONDS) // 读取服务器返回数据的时长  s
      .writeTimeout(10, TimeUnit.SECONDS) // 向服务器写入数据的时长，默认--10s
      .retryOnConnectionFailure(true) // 重连
      .followRedirects(false)// 重定向
      .cache(Cache(File("data/user/0/com.wn.caiiao/cache", "okHttp"), 1024))// 本地缓存
      .cookieJar(LocalCookieKar())// 本地 cookies 持久化存储
      .addInterceptor(HostInterceptor()) // BaseUrl 拦截
      .addNetworkInterceptor(RetryInterceptor(1))// 重试
      .addNetworkInterceptor(CnInterceptor()) // 公共 header的拦截器
      // 添加网络拦截器，可以对okHttp的网络请求做拦截处理，不同于应用拦截器，这里能感知所有网络状态，比如重定向
      .addNetworkInterceptor(HttpLogInterceptor {
        logTag("<wn--KtHttp>")
        // 调试模式
        if (BuildConfig.DEBUG)
          logLevel(LogLevel.BODY) // 设置 打印所有
        else
          logLevel(LogLevel.NONE) // 不打印
      })
      .build()
  }

  //  创建  Retrofit.Builder
  private val retrofitBuilder by lazy {
    Retrofit.Builder()
      .addConverterFactory(GsonConverterFactory.create())
      .addCallAdapterFactory(LiveDataCallAdapterFactory())
  }

  //  创建  Retrofit  有拦截器  HostInterceptor 替换 baseHost的拦截器
  //  修改 BaseURL  需要 修改 MMKV--SP_KEY_BASE_HOST
  private val retrofit: Retrofit by lazy {
    retrofitBuilder.baseUrl(getBaseHost()).client(mOkClient).build()
  }

  //  创建 API 接口
  fun <T> createApi(clazz: Class<T>): T = retrofit.create(clazz) as T
}